/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.core;

import com.inspur.edp.bef.core.debug.NetworkAddressUtil;
import com.inspur.edp.bef.core.session.FuncSessionManager;
import com.inspur.edp.cdp.common.utils.json.JsonUtil;
import com.inspur.edp.debugtool.api.Tracer;
import com.inspur.edp.debugtool.api.constant.ComponentConstant;
import com.inspur.edp.debugtool.api.entity.Span;
import io.iec.edp.caf.boot.context.CAFContext;
import io.iec.edp.caf.core.context.BizContext;
import java.lang.reflect.Array;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DebugAdapter {

  public static final String Mark_Begin = "funcBegin";
  public static final String Mark_Running = "funcRunning";
  public static final String Mark_End = "funcEnd";

  public final static String buildString(Object value, boolean fast) {
    if (value == null) {
      return "[[null]]";
    }
    if (value instanceof String) {
      return (String) value;
    }
    if (value instanceof Iterable) {
      Iterator iterator = ((Iterable) value).iterator();
      StringBuilder sb = new StringBuilder("[");
      int count = 0;
      while (iterator.hasNext()) {
        sb.append(buildString(iterator.next(), fast)).append(";");
        if (count++ > 2000 || (fast && count > 50)) {
          sb.append("等")
            .append(value instanceof Collection ? ((Collection) value).size() : "多")
            .append("项;");
          break;
        }
      }
      sb.append("]");
      return sb.toString();
    }
    if (fast) {
      return value.toString();
    }
    try {
      return JsonUtil.toJson(value);
    } catch (Throwable r) {
      return value.toString();
    }
  }


  private static final String Prefix = "[befDbg]";
  private static final String Layer = "BizEntityFramework";

  public static final void trace(String methodName, String mark, Exception e, Object... info) {
//    log(methodName, mark, info, e);

    if (!Tracer.isEnabled()) {
      return;
    }
    Span span = Tracer.createSpan();
//    span.setLayer();
    span.setEndpointName(Prefix + methodName + ":" + mark);
    span.setLayer(Layer);
    span.setComponent(ComponentConstant.SERVER);
    span.addTag("name", methodName);
    span.addTag("threadId", Long.toString(Thread.currentThread().getId()));
    if (mark != null) {
      span.addTag("mark", mark);
    }
    span.addTag("threadId", String.valueOf(Thread.currentThread().getId()));
    BizContext bizCtx = CAFContext.current.getBizContext();
    if (bizCtx != null) {
      span.addTag("bizCtxId", bizCtx.getId());
      if (bizCtx.getItems() != null && !bizCtx.getItems().isEmpty()) {
        span.addTag("bizCtxItems", buildString(bizCtx.getItems(), true));
      }
      String currentFuncSessionId = FuncSessionManager.getCurrentFuncSessionId();
      if (currentFuncSessionId != null) {
        span.addTag("befSessionId", currentFuncSessionId);
      }
    }
    if (info != null) {
      int index = 1;
      for(Object item : info) {
        span.addTag("info"+(index++), DebugAdapter.buildString(item, false));
        if (index==3){
          break;
        }
      }
    }
    span.addTag("info3",getAddressInfo().toString());
    if (e != null) {
      Tracer.stopSpan(span, e);
    } else {
      Tracer.stopSpan(span);
    }
  }

  private static void log(String methodName, String mark, Object[] info, Exception e) {
    String errorInfo = Prefix.concat(methodName).concat(":").concat(String.valueOf(mark));
    if (info != null) {
      errorInfo = errorInfo.concat(":").concat("{}");
    }
    BizContext bizCtx = CAFContext.current.getBizContext();
    if (bizCtx != null) {
      errorInfo = errorInfo.concat("(bizContextId:").concat(bizCtx.getId()).concat(")");
    }
    if (e == null) {
      log.debug(errorInfo, info);
    } else {
      log.error(errorInfo, e);
    }
  }

  public static List<String> getAddressInfo(){
    List<String> hostInfo = new ArrayList<>();
    try {
      HashMap<String, String> hashMap = NetworkAddressUtil.getLocalAddressInfo();
      hostInfo.add("IP地址："+ hashMap.get("address"));
      hostInfo.add("主机名称："+hashMap.get("hostname"));
      hostInfo.add("主机域名："+ hashMap.get("hostdomain"));
    } catch (Exception e) {
      e.printStackTrace();
    }
    return hostInfo;
  }
}
